import { makeObservable, observable, action, computed, makeAutoObservable, runInAction } from "mobx";

class Counter {
  // this.count = 0
  // 给类的实例对象添加属性count，初始化值为0
  count = 0;

  // 计算属性
  // 只能读取
  // 定义属性oddOrEven，和属性的读取的方法
  get oddOrEven() {
    return this.count % 2 === 0 ? "偶数" : "奇数";
  }

  // 类的构造方法
  // 当你new调用类，类会自动触发constructor方法
  constructor() {
    // this就是类的实例对象
    /*
      什么是响应式？

        React中如果直接更新数据，只会数据变化，用户界面不会变。
        React中需要调用setXxx方法，来更新数据，此时才会更新用户界面。

        响应式：当你直接更新数据，数据变同时用户界面也变。
        这样的数据，也叫做响应式的数据。

        makeObservable就能让数据变成响应式

        所以将来this.count++，数据会变，用户界面也会变化（就不用调用setXxx方法了）
    */
    // 让this（类的实例对象）变成响应式
    // 第二个参数，让this上的哪些变成响应式
    // makeObservable(this, {
    //   count: observable, // observable定义响应式数据
    //   increment: action, // action定义更新更新数据的方法
    //   decrement: action,
    //   incrementIffOdd: action,
    //   incrementAsync: action,
    //   oddOrEven: computed,
    // });

    makeAutoObservable(this);
  }

  // xxx = () => {} // 给实例对象直接添加方法
  // xxx() {} // 给原型对象添加方法

  // 更新数据要求定义方法 - action
  increment() {
    // 类中的函数，this指向？实例对象
    this.count++; // 因为count是响应式的。所以即会更新数据，同时会触发用户界面的更新
  }

  decrement() {
    this.count--;
  }

  incrementIffOdd() {
    if (this.count % 2 === 0) return;
    this.count++;
  }

  incrementAsync() {
    // 1. 内部没有使用action
    // setTimeout(() => {
    //   // 箭头函数的this指向外层函数的this
    //   // 外层函数的this指向实例对象，所以箭头函数的this才是实例对象
    //   this.count++;
    // }, 1000);

    // 2. 使用action函数
    // setTimeout(() => {
    //   const newAction = action("incrementAsync", () => {
    //     this.count++;
    //   });
    //   newAction();
    // }, 1000);

    // 3. action函数的语法糖（语法的简写）
    setTimeout(() => {
      // action就没有名字了
      runInAction(() => {
        this.count++;
      });
    }, 1000);

    // setTimeout(function () {
    //   // 普通函数不行，this指向window，严格模式下是undefined
    //   this.count++;
    // }, 1000);
  }
}

/*
  暴露出去的counter：
    counter: {
      count: 0 // 这个数据是响应式的
    }
*/
export default new Counter();
